/*
  sort
  题目描述
    输入整数 n,k, 然后输入 n 个正整数，
    按从小到大的顺序输出前 k 个正整数。
    相同的数占据多个排名，例如对 1,4,3,4,2,4,7,5,6, 从小到大的顺序是 1,2,3,4,4,4,5,6,7.
  输入描述
    第 1 行，2 个正整数 n,k
    第 2 行，n 个正整数 a1, a2, ⋯, an
  输出描述
    输出 a1, a2, ⋯, an 从小到大排序后的前 k 个正整数
  样例1
    输入
      9 5
      1 4 3 4 2 4 7 5 6
    输出
      1 2 3 4 4
  提示
    1 ≤ k ≤ n ≤ 5 * 10^6
    1 ≤ ai ≤ 10^5
*/

#include <bits/stdc++.h>

using namespace std;

int a[5000005] = {};  // 数组 a, 存放待排序的若干个正整数, 排序后的数也存放在该数组中
int b[5000005] = {};  // 临时数组

/*
  函数功能:
    使用归并排序算法, 对数组 a[s] ~ a[e] 按从小到大的顺序进行排序,
    完成排序后, a[s] ~ a[e] 为从小到大的顺序。
  参数说明:
     s  -- 对数组 a[] 进行排序的开始下标
     e  -- 对数组 a[] 进行排序的结束下标，其中 e >= s
  小结:
     归并排序使用了递归的方式进行编码实现!
*/
void f(int s, int e) {
    if (s == e) { // 当序列中只有 1 个数时，不需要其他排序操作，已经排好序了!
        return;
    }

    int mid = (s + e) / 2;

    // 1. 对数组 a 的左半部分(a[s] ~ a[mid]), 使用归并排序的方法按从小到大的顺序进行排序
    f(s, mid);

    // 2. 对数组 a 的右半部分(a[mid + 1] ~ a[e]), 使用归并排序的方法按从小到大的顺序进行排序
    f(mid + 1, e);

    // 3. 将数组 a 的左半部分和右半部进行合并, 合并成一个从小到大的有序数组
    //    实现方法:
    //      a[i] 和 a[j] 进行比较，将小的数放到 b[k];
    //      然后将下标 i或j、k 往后移动 1 位(即+1)
    //      依次类推, 即可完成将左半部分和右半部分的合并，合并后的数存放在临时数序 b 中!
    int i = s, j = mid + 1, k = s;
    while (i <= mid && j <= e) {
        if (a[i] <= a[j]) {
            b[k++] = a[i++];
        } else {
            b[k++] = a[j++];
        }
    }
    while (i <= mid) {
        b[k++] = a[i++];
    }
    while (j <= e) {
        b[k++] = a[j++];
    }

    // 4. 使用数组 b 中的元素为数组 a 中的对应元素赋值!
    for (int i = s; i <= e; i++) {
        a[i] = b[i];
    }
}

int main() {
    int n, k;

    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    // 使用归并排序算法, 对 a[1] ~ a[n] 按从小到大的顺序进行排序
    f(1, n);

    for (int i = 1; i <= k; i++) {
        cout << a[i] << " ";
    }

    return 0;
}